/*
 *  Copyright (C) 2011  Clint Priest
 *
 *  This file is part of Snap Graph.
 *
 *  Snap Graph is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Snap Graph is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Snap Graph.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
 
var UserSelection = Class.create( {
	SelectedElements: {
		get: function() { return this._SelectedElements; },
		set: function(x) { this._SelectedElements = x; this.CalculateRowHeaders(); },
	},
	initialize: function() {
		this.HeaderHighlighter = new ElementHighlighter('#0000FF', .3);
		this.CellHighlighter = new ElementHighlighter('#00FF00', .3);
	},
	
	/** Highlights the cells and row headers */
	Highlight: function() {
		this.HeaderHighlighter.HighlightElements(this.RowHeaders.concat(this.ColHeaders));
		this.CellHighlighter.HighlightElements(this.SelectedElements);
	},
	
	Unhighlight: function() {
		this.HeaderHighlighter.Clear();
		this.CellHighlighter.Clear();
	},

	/** Calculates the row headers for each selected element */
	CalculateRowHeaders: function() {
		this.RowHeaders = [ ];
		this.ColHeaders = [ ];

		this.SelectedElements.forEach( function(elem) {
			if(!elem.SnapRowHeader || !elem.SnapColHeader)
				this.DetermineRowColHeader(elem);
			this.RowHeaders.push(elem.SnapRowHeader);
			this.ColHeaders.push(elem.SnapColHeader);
		}, this );
		this.RowHeaders = this.RowHeaders.uniq();
		this.ColHeaders = this.ColHeaders.uniq();
	},

	/* Finds the row "Title" and column "Title" cells */
	DetermineRowColHeader: function(elem) {
		var PreviousSiblings = elem.previousSiblings();
				
		/* Find SnapRowHeader */
		elem.SnapRowHeader = elem.previous('TH');
		
		/* Search previous <TR> elements for corresponding <TH> at same offset as elem */
		var ColIndex = PreviousSiblings.reduce( function(acc, elem) { return acc + parseInt(elem.getAttribute('colspan') || 1); }, 0);
		
		var Row = elem.up();
		while(Row && !elem.SnapColHeader) {
			var Descendants = Row.immediateDescendants(), Col=0;
			for(var i=0, Descendant; Descendant = Descendants[i]; i++) {
				Col += parseInt(Descendant.getAttribute('colspan') || 1);
				if(Col > ColIndex) {
					if(Descendant.tagName == 'TH')
						elem.SnapColHeader = Descendant; /* Breaks While */
					break; /* Breaks for */
				}
			}
				
			Row = Row.previous();
		}
	},
} );